/*
 *
 * System2 Simulation Framework
 * Copyright (C) 2011 - 2012 Jacob Dawid
 * jacob.dawid@googlemail.com
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 *
 */

#ifndef UNIT_H
#define UNIT_H

#include <QString>
#include <QMap>

#include "globaldefines.h"

namespace System2 {
    /**
      * \class Unit
      * \author Jacob Dawid <jacob.dawid@googlemail.com>
      * \date 16.01.2012
      */
    class Unit {
    public:
        enum PrimaryUnit {
            Volt,
            Ampere,
            Ohm,
            Hertz,
            Seconds,
            Bit,
            Byte,
            Without
        };

        enum Prefix {
            Yobi,
            Zebi,
            Exbi,
            Pebi,
            Tebi,
            Gibi,
            Mebi,
            Kibi,
            Yocto,
            Zepto,
            Atto,
            Femto,
            Pico,
            Nano,
            Micro,
            Milli,
            Centi,
            Deci,
            None,
            Deca,
            Hecto,
            Kilo,
            Mega,
            Giga,
            Tera,
            Peta,
            Exa,
            Zetta,
            Yotta
        };

        Unit(PrimaryUnit primaryUnit = Without, Prefix prefix = None);
        Unit(const Unit& other);

        bool operator == (const Unit& other) {
            if(other.m_prefix == this->m_prefix)
                if(other.m_primaryUnit == this->m_primaryUnit)
                    return true;
            return false;
        }

        bool isCompatibleWith(const Unit& unit) const;
        Number adapt(const Unit& unit);

        PrimaryUnit primaryUnit() const;
        Prefix prefix() const;
        Number prefixValue() const;

        QString toString();

    private:
        PrimaryUnit m_primaryUnit;
        Prefix m_prefix;

        static QMap<Prefix, QString> initializePrefixes();
        static QMap<Prefix, Number> initializePrefixValues();
        static QMap<PrimaryUnit, QString> initializePrimaryUnits();

        static QMap<Prefix, QString> m_prefixes;
        static QMap<Prefix, Number> m_prefixValues;
        static QMap<PrimaryUnit, QString> m_primaryUnits;
    };
}

#endif // UNIT_H
